/**
 * Chat UI Manager for room page
 */
import { DOMUtils, StringUtils } from '../common/utils.js';
import { DataTransfer, URLUtils, NavigationUtils } from '../common/storage.js';

export class ChatUIManager {
    constructor() {
        this.elements = {};
        this.users = new Map();
        this.messages = [];
        this.isScrolledToBottom = true;
        
        this.cacheElements();
        this.setupEventListeners();
    }

    cacheElements() {
        this.elements = {
            // Room elements
            roomTitle: DOMUtils.getElementById('room-title'),
            roomMemberCount: DOMUtils.getElementById('room-member-count'),
            
            // Messages
            messagesContainer: DOMUtils.getElementById('messages-container'),
            messagesList: DOMUtils.getElementById('messages-list'),
            
            // Message input
            messageForm: DOMUtils.getElementById('message-form'),
            messageInput: DOMUtils.getElementById('message-input'),
            sendBtn: DOMUtils.getElementById('send-btn'),
            
            // Users list
            usersList: DOMUtils.getElementById('users-list'),
            
            // Actions
            inviteLinkBtn: DOMUtils.getElementById('invite-link-btn'),
            leaveRoomBtn: DOMUtils.getElementById('leave-room-btn'),
            
            // Modal
            inviteModal: DOMUtils.getElementById('invite-modal'),
            inviteLinkInput: DOMUtils.getElementById('invite-link-input'),
            copyInviteBtn: DOMUtils.getElementById('copy-invite-btn'),
            inviteModalClose: DOMUtils.getElementById('invite-modal-close'),
            
            // Connection status
            connectionStatus: DOMUtils.getElementById('connection-status')
        };
    }

    setupEventListeners() {
        // Message form submission
        DOMUtils.addEventListener(this.elements.messageForm, 'submit', (e) => {
            e.preventDefault();
            this.handleSendMessage();
        });

        // Leave room
        DOMUtils.addEventListener(this.elements.leaveRoomBtn, 'click', () => {
            this.handleLeaveRoom();
        });

        // Invite link
        DOMUtils.addEventListener(this.elements.inviteLinkBtn, 'click', () => {
            this.showInviteModal();
        });

        // Copy invite link
        DOMUtils.addEventListener(this.elements.copyInviteBtn, 'click', () => {
            this.copyInviteLink();
        });

        // Close invite modal
        DOMUtils.addEventListener(this.elements.inviteModalClose, 'click', () => {
            this.hideInviteModal();
        });

        // Close modal by clicking outside
        DOMUtils.addEventListener(this.elements.inviteModal, 'click', (e) => {
            if (e.target === this.elements.inviteModal) {
                this.hideInviteModal();
            }
        });

        // Auto-resize message input
        DOMUtils.addEventListener(this.elements.messageInput, 'input', () => {
            this.autoResizeInput();
        });

        // Enter key handling
        DOMUtils.addEventListener(this.elements.messageInput, 'keydown', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                this.handleSendMessage();
            }
        });

        // Scroll detection
        DOMUtils.addEventListener(this.elements.messagesContainer, 'scroll', () => {
            this.handleScroll();
        });
    }

    /**
     * Update room information
     */
    updateRoomInfo(roomData) {
        if (roomData.name) {
            DOMUtils.setTextContent(this.elements.roomTitle, roomData.name);
            document.title = `${roomData.name} - LAN Chat Room`;
        }

        if (roomData.memberCount !== undefined) {
            DOMUtils.setTextContent(this.elements.roomMemberCount, roomData.memberCount);
        }

        // Update invite link if available
        if (roomData.inviteCode) {
            const inviteUrl = `${window.location.origin}/?invite=${roomData.inviteCode}`;
            if (this.elements.inviteLinkInput) {
                this.elements.inviteLinkInput.value = inviteUrl;
            }
        }
    }

    /**
     * Add message to chat
     */
    addMessage(messageData) {
        const message = {
            id: messageData.id || Date.now() + Math.random(),
            content: messageData.content,
            author: messageData.user?.nickname || messageData.author,
            userId: messageData.user?.id || messageData.userId,
            timestamp: messageData.timestamp || new Date().toISOString(),
            type: messageData.type || 'user'
        };

        this.messages.push(message);
        this.renderMessage(message);
        this.scrollToBottom();
    }

    /**
     * Add system message
     */
    addSystemMessage(content) {
        const message = {
            id: Date.now() + Math.random(),
            content,
            type: 'system',
            timestamp: new Date().toISOString()
        };

        this.messages.push(message);
        this.renderMessage(message);
        this.scrollToBottom();
    }

    /**
     * Render a single message
     */
    renderMessage(message) {
        const messageElement = document.createElement('div');
        messageElement.className = 'message';
        messageElement.dataset.messageId = message.id;

        if (message.type === 'system') {
            messageElement.classList.add('message-system');
            messageElement.innerHTML = `
                <div class="message-content">
                    <div class="message-text">${StringUtils.escapeHTML(message.content)}</div>
                    <div class="message-time">${StringUtils.formatTime(message.timestamp)}</div>
                </div>
            `;
        } else {
            const session = DataTransfer.getSession();
            const isOwnMessage = session && message.userId === session.userId;
            
            if (isOwnMessage) {
                messageElement.classList.add('message-own');
            } else {
                messageElement.classList.add('message-other');
            }

            const avatar = this.generateAvatar(message.author);
            
            messageElement.innerHTML = `
                <div class="message-avatar">${avatar}</div>
                <div class="message-content">
                    ${!isOwnMessage ? `<div class="message-author">${StringUtils.escapeHTML(message.author)}</div>` : ''}
                    <div class="message-text">${StringUtils.escapeHTML(message.content)}</div>
                    <div class="message-time">${StringUtils.formatTime(message.timestamp)}</div>
                </div>
            `;
        }

        this.elements.messagesList.appendChild(messageElement);
    }

    /**
     * Update users list
     */
    updateUsersList(users) {
        this.users.clear();
        users.forEach(user => this.users.set(user.id, user));

        DOMUtils.clear(this.elements.usersList);

        users.forEach(user => {
            const userElement = document.createElement('div');
            userElement.className = 'user-item';
            userElement.dataset.userId = user.id;

            const avatar = this.generateAvatar(user.nickname);
            const session = DataTransfer.getSession();
            const isCurrentUser = session && user.id === session.userId;

            userElement.innerHTML = `
                <div class="user-avatar">${avatar}</div>
                <div class="user-info">
                    <div class="user-name">
                        ${StringUtils.escapeHTML(user.nickname)}
                        ${isCurrentUser ? ' (You)' : ''}
                        ${user.isOwner ? ' 👑' : ''}
                    </div>
                    <div class="user-status user-online">Online</div>
                </div>
            `;

            this.elements.usersList.appendChild(userElement);
        });
    }

    /**
     * Handle user joined
     */
    handleUserJoined(userData) {
        this.addSystemMessage(`${userData.user.nickname} joined the room`);
        
        // User list will be updated via room update event
    }

    /**
     * Handle user left
     */
    handleUserLeft(userData) {
        this.addSystemMessage(`${userData.user.nickname} left the room`);
        
        // User list will be updated via room update event
    }

    /**
     * Handle send message
     */
    handleSendMessage() {
        const content = this.elements.messageInput.value.trim();
        
        if (!content) return;

        // Dispatch event for WebSocket manager to handle
        const event = new CustomEvent('send-message', {
            detail: { content }
        });
        document.dispatchEvent(event);

        // Clear input
        this.elements.messageInput.value = '';
        this.autoResizeInput();
    }

    /**
     * Handle leave room
     */
    handleLeaveRoom() {
        if (confirm('Are you sure you want to leave this room?')) {
            // Dispatch event for app to handle
            const event = new CustomEvent('leave-room');
            document.dispatchEvent(event);
        }
    }

    /**
     * Show invite modal
     */
    showInviteModal() {
        DOMUtils.show(this.elements.inviteModal);
        
        // Focus the input for easy copying
        if (this.elements.inviteLinkInput) {
            this.elements.inviteLinkInput.select();
        }
    }

    /**
     * Hide invite modal
     */
    hideInviteModal() {
        DOMUtils.hide(this.elements.inviteModal);
    }

    /**
     * Copy invite link to clipboard
     */
    async copyInviteLink() {
        try {
            if (this.elements.inviteLinkInput) {
                await navigator.clipboard.writeText(this.elements.inviteLinkInput.value);
                
                // Update button text temporarily
                const originalText = this.elements.copyInviteBtn.textContent;
                this.elements.copyInviteBtn.textContent = 'Copied!';
                setTimeout(() => {
                    this.elements.copyInviteBtn.textContent = originalText;
                }, 2000);
            }
        } catch (error) {
            console.error('Failed to copy invite link:', error);
            
            // Fallback: select the text
            if (this.elements.inviteLinkInput) {
                this.elements.inviteLinkInput.select();
            }
        }
    }

    /**
     * Update connection status
     * @param {string} status - 'Connected', 'Disconnected', 'Reconnecting...'
     * @param {boolean} isConnected - Connection state
     */
    updateConnectionStatus(status, isConnected = false) {
        if (!this.elements.connectionStatus) return;
        
        const statusText = this.elements.connectionStatus.querySelector('.status-text');
        const indicator = this.elements.connectionStatus.querySelector('.connection-indicator');
        
        if (statusText) {
            DOMUtils.setTextContent(statusText, status);
        } else {
            // Fallback if no status-text element
            DOMUtils.setTextContent(this.elements.connectionStatus, status);
        }
        
        // Update CSS classes based on connection state
        this.elements.connectionStatus.classList.remove('connected', 'disconnected', 'reconnecting');
        
        if (isConnected) {
            this.elements.connectionStatus.classList.add('connected');
            if (indicator) {
                indicator.classList.remove('pulse');
            }
            
            // Hide after a delay for connected status
            setTimeout(() => {
                DOMUtils.hide(this.elements.connectionStatus);
            }, 3000);
        } else if (status.toLowerCase().includes('reconnect')) {
            this.elements.connectionStatus.classList.add('reconnecting');
            if (indicator) {
                indicator.classList.add('pulse');
            }
            DOMUtils.show(this.elements.connectionStatus);
        } else {
            this.elements.connectionStatus.classList.add('disconnected');
            if (indicator) {
                indicator.classList.remove('pulse');
            }
            DOMUtils.show(this.elements.connectionStatus);
        }
    }

    /**
     * Generate avatar initials
     */
    generateAvatar(nickname) {
        if (!nickname) return '?';
        
        // Get first letter of each word, max 2 letters
        const words = nickname.trim().split(/\s+/);
        const initials = words
            .slice(0, 2)
            .map(word => word.charAt(0).toUpperCase())
            .join('');
        
        return initials || '?';
    }

    /**
     * Auto-resize message input
     */
    autoResizeInput() {
        const input = this.elements.messageInput;
        input.style.height = 'auto';
        input.style.height = Math.min(input.scrollHeight, 120) + 'px';
    }

    /**
     * Handle scroll events
     */
    handleScroll() {
        const container = this.elements.messagesContainer;
        const threshold = 50; // pixels from bottom
        
        this.isScrolledToBottom = 
            container.scrollTop + container.clientHeight >= 
            container.scrollHeight - threshold;
    }

    /**
     * Scroll to bottom of messages
     */
    scrollToBottom() {
        if (this.isScrolledToBottom) {
            setTimeout(() => {
                const container = this.elements.messagesContainer;
                container.scrollTop = container.scrollHeight;
            }, 0);
        }
    }

    /**
     * Clear all messages
     */
    clearMessages() {
        this.messages = [];
        DOMUtils.clear(this.elements.messagesList);
    }

    /**
     * Set input state (enabled/disabled)
     * @param {boolean} enabled
     */
    setInputState(enabled) {
        if (this.elements.messageInput) {
            if (enabled) {
                DOMUtils.enable(this.elements.messageInput);
                this.elements.messageInput.placeholder = 'Type your message...';
            } else {
                DOMUtils.disable(this.elements.messageInput);
                this.elements.messageInput.placeholder = 'Connecting...';
            }
        }
        
        if (this.elements.sendBtn) {
            if (enabled) {
                DOMUtils.enable(this.elements.sendBtn);
            } else {
                DOMUtils.disable(this.elements.sendBtn);
            }
        }
    }

    /**
     * Show error message with improved UI feedback
     * @param {string} message Error message
     * @param {string} type Error type (error, warning, info)
     */
    showError(message, type = 'error') {
        // Create temporary error notification
        const notification = document.createElement('div');
        notification.className = `notification notification-${type}`;
        notification.innerHTML = `
            <div class="notification-content">
                <span class="notification-icon">${this.getNotificationIcon(type)}</span>
                <span class="notification-message">${StringUtils.escapeHTML(message)}</span>
                <button class="notification-close">&times;</button>
            </div>
        `;
        
        // Add styles for notification if not already added
        this.addNotificationStyles();
        
        // Add to page
        document.body.appendChild(notification);
        
        // Auto remove after 5 seconds
        setTimeout(() => {
            if (notification.parentNode) {
                notification.style.opacity = '0';
                setTimeout(() => {
                    if (notification.parentNode) {
                        notification.parentNode.removeChild(notification);
                    }
                }, 300);
            }
        }, 5000);
        
        // Close button handler
        const closeBtn = notification.querySelector('.notification-close');
        if (closeBtn) {
            DOMUtils.addEventListener(closeBtn, 'click', () => {
                if (notification.parentNode) {
                    notification.style.opacity = '0';
                    setTimeout(() => {
                        if (notification.parentNode) {
                            notification.parentNode.removeChild(notification);
                        }
                    }, 300);
                }
            });
        }
        
        // Also dispatch event for main app to handle
        const event = new CustomEvent('show-error', {
            detail: { message, type }
        });
        document.dispatchEvent(event);
    }

    /**
     * Get notification icon based on type
     * @param {string} type
     * @returns {string}
     */
    getNotificationIcon(type) {
        switch (type) {
            case 'error': return '❌';
            case 'warning': return '⚠️';
            case 'info': return 'ℹ️';
            case 'success': return '✅';
            default: return 'ℹ️';
        }
    }

    /**
     * Add notification styles if not already present
     */
    addNotificationStyles() {
        if (document.getElementById('notification-styles')) return;
        
        const style = document.createElement('style');
        style.id = 'notification-styles';
        style.textContent = `
            .notification {
                position: fixed;
                top: 20px;
                right: 20px;
                background: white;
                border-radius: 8px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
                z-index: 10000;
                opacity: 1;
                transition: opacity 0.3s ease;
                max-width: 400px;
                border-left: 4px solid #ccc;
            }
            .notification-error {
                border-left-color: #dc2626;
            }
            .notification-warning {
                border-left-color: #d97706;
            }
            .notification-info {
                border-left-color: #2563eb;
            }
            .notification-success {
                border-left-color: #059669;
            }
            .notification-content {
                display: flex;
                align-items: center;
                gap: 12px;
                padding: 16px;
            }
            .notification-icon {
                font-size: 18px;
                flex-shrink: 0;
            }
            .notification-message {
                flex: 1;
                color: #374151;
                font-size: 14px;
                line-height: 1.4;
            }
            .notification-close {
                background: none;
                border: none;
                font-size: 18px;
                cursor: pointer;
                color: #6b7280;
                padding: 0;
                width: 24px;
                height: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 4px;
                flex-shrink: 0;
            }
            .notification-close:hover {
                background-color: #f3f4f6;
                color: #374151;
            }
        `;
        
        document.head.appendChild(style);
    }
}